import Map from '../class/Map';

/**
 * 事件对象
 * @param {Function} fn
 * @param {Boolean} state
 */
function EventFn(fn, state) {

	let _fn = fn;
	let _state = state || true;

	this.fn = function() {
		return _fn;
	}

	this.state = function() {
		return _state;
	}

	this.open = function() {
		_state = true;
	}

	this.close = function() {
		_state = false;
	}

}

/**
 * dom事件包装对象
 * @param {Dom} dom
 */
function DomListenerWrap(dom) {

	const GLOBAL = {
		START_Y: undefined,
		SLIDE_UP_SCROLL: false,
		SLIDE_UP_SCROLL_STOP: false,
		SLIDE_DOWN_SCROLL: false,
		SLIDE_DOWN_SCROLL_STOP: false
	}; // 全局对象

	const ENTER_DOWN = 'enterDown'; // 回车键监听
	const SLIDE_UP = 'slideUp'; // 上滑事件监听
	const SLIDE_DOWN = 'slideDown'; // 下滑事件监听
	const SLIDE_UP_SCROLL = 'slideUpScroll'; // 上滑事件开始直到滚动结束的监听
	const SLIDE_DOWN_SCROLL = 'slideDownScroll'; // 下滑事件开始直到滚动结束的监听
	const SCROLL_STOP = 'scrollStop'; // 滚动结束事件

	let _self = this; // 自身引用

	let _dom = dom;
	let _listener = new Map(); // Map<listener, EventFn[]>

	let _scrollStop = function() {
		_addEvent('scroll', function() {
			GLOBAL.ROLLING = 2;
		});
		setTimeout(function() {
			if(GLOBAL.ROLLING !== 2) {
				GLOBAL.ROLLING
			}
		})
	}

	// 监听兼容(注意:在attachEvent下的this为window)
	let _addEvent = function(listener, fn) {
		if(dom.addEventListener) {
			dom.addEventListener(listener, fn, false); // 针对FF与chrome
		} else {
			dom.attachEvent('on' + listener, fn); // 针对低版本ie
		}
	}

	// 添加监听的方法
	let _addEventListener = function(listener) {
		let listenerName = listener;
		// 特殊监听的处理
		switch(listener) {
			case ENTER_DOWN:
				listenerName = 'keydown';
				break;
			case SLIDE_UP:
			case SLIDE_DOWN:
				_addEvent('touchstart', function() {
					GLOBAL.START_Y = (event || window.event).touches[0].screenY;
				})
				listenerName = 'touchend';
				break;
			case SLIDE_UP_SCROLL:
				let slideUpDownFn = function() {
					GLOBAL.SLIDE_UP_SCROLL = true;
				}
				_self.add(SLIDE_UP, slideUpDownFn);
				listenerName = 'scroll';
				break;
			case SLIDE_DOWN_SCROLL:
				let slideDownDownFn = function() {
					GLOBAL.SLIDE_DOWN_SCROLL = true;
				}
				_self.add(SLIDE_DOWN, slideDownDownFn);
				listenerName = 'scroll';
				break;
			case SCROLL_STOP:
				listenerName = 'scroll';
				break;

		}
		// 添加监听
		_addEvent(listenerName, function() {
			let eventFns = _listener.get(listener);
			if(!eventFns) return;
			// 特殊监听的处理
			switch(listener) {
				case ENTER_DOWN:
					let e = event || window.event;
					if((e.keyCode || e.which) != 13) return;
					break;
				case SLIDE_UP:
					let slideUpEndY = (event || window.event).changedTouches[0].screenY;
					if(GLOBAL.START_Y - slideUpEndY < 40) return;
					break;
				case SLIDE_DOWN:
					let slideDownendY = (event || window.event).changedTouches[0].screenY;
					if(slideDownendY - GLOBAL.START_Y < 40) return;
					break;
				case SLIDE_UP_SCROLL:
					if(GLOBAL.SLIDE_UP_SCROLL) {
						if(!GLOBAL.SLIDE_UP_SCROLL_STOP) {
							GLOBAL.SLIDE_UP_SCROLL_STOP = true;
							let slideUpClose = function() {
								GLOBAL.SLIDE_UP_SCROLL = false;
								GLOBAL.SLIDE_UP_SCROLL_STOP = false;
								_self.remove(SLIDE_DOWN, slideUpClose);
							}
							_self.add(SCROLL_STOP, slideUpClose);
						}
					} else {
						return;
					}
					break;
				case SLIDE_DOWN_SCROLL:
					if(GLOBAL.SLIDE_DOWN_SCROLL) {
						if(!GLOBAL.SLIDE_DOWN_SCROLL_STOP) {
							GLOBAL.SLIDE_DOWN_SCROLL_STOP = true;
							let slideDownClose = function() {
								GLOBAL.SLIDE_DOWN_SCROLL = false;
								GLOBAL.SLIDE_DOWN_SCROLL_STOP = false;
								_self.remove(SLIDE_DOWN, slideDownClose);
							}
							_self.add(SCROLL_STOP, slideDownClose);
						}
					} else {
						return;
					}
					break;
				case SCROLL_STOP:
					let scrollTimer;
					_addEvent('scroll', function() {
						if(scrollTimer) clearTimeout(scrollTimer);
						scrollTimer = setTimeout(function() {
							for(let i = 0; i < eventFns.length; i++) {
								if(eventFns[i] && eventFns[i].state())(eventFns[i].fn())();
							}
						}, 100);
					});
					return;
					break;
			}
			for(let i = 0; i < eventFns.length; i++) {
				if(eventFns[i] && eventFns[i].state())(eventFns[i].fn())();
			}
		});
	}

	/**
	 * 添加监听
	 * @param {String} listener
	 * @param {Function} eFn
	 */
	this.add = function(listener, eFn) {
		if(!eFn) return;
		let eventFns = _listener.get(listener);
		if(!eventFns) {
			_addEventListener(listener); // 启动监听
			eventFns = new Array();
			_listener.put(listener, eventFns);
		}
		let eventFn = new EventFn(eFn, true);
		eventFns.push(eventFn);
	}

	/**
	 * 删除监听
	 * @param {String} listener
	 * @param {Function} eFn
	 */
	this.remove = function(listener, eFn) {
		if(!eFn) {
			// 移除所有该监听下的函数
			_listener.remove(listener);
			return;
		}
		// 移除该监听下的eFn函数
		let eventFns = _listener.get(listener);
		if(!eventFns) return;
		for(let i = 0; i < eventFns.length; i++) {
			if(eventFns[i] && eventFns[i].fn() === eFn) delete eventFns[i];
		}
	}

	/**
	 * 开启监听
	 * @param {String} listener
	 * @param {Function} eFn
	 */
	this.open = function(listener, eFn) {
		let eventFns = _listener.get(listener);
		if(!eventFns) return;
		for(let i = 0; i < eventFns.length; i++) {
			if((eFn && eventFns[i] && eventFns[i].fn()) || (!eFn && eventFns[i])) eventFns[i].open();
		}
	}

	/**
	 * 关闭监听
	 * @param {String} listener
	 * @param {Function} eFn
	 */
	this.close = function(listener, eFn) {
		let eventFns = _listener.get(listener);
		if(!eventFns) return;
		for(let i = 0; i < eventFns.length; i++) {
			if((eFn && eventFns[i] && eventFns[i].fn()) || (!eFn && eventFns[i])) eventFns[i].close();
		}
		for(let i = 0; i < eventFns.length; i++) {
			console.log(eventFns[i].state())
		}
	}
}

/**
 * 监听管理器
 */
function ListenerManager() {

	let _store = new Map(); // Map<dom, DomListenerWrap>

	this.add = function(dom, listener, eFn) {
		if(!dom) return;
		let domListenerWrap = _store.get(dom);
		if(!domListenerWrap) {
			domListenerWrap = new DomListenerWrap(dom);
			_store.put(dom, domListenerWrap);
		}
		domListenerWrap.add(listener, eFn);
	}

	this.remove = function(dom, listener, eFn) {
		let domListenerWrap = _store.get(dom);
		if(!domListenerWrap) return;
		domListenerWrap.remove(listener, eFn);
	}

	this.open = function(dom, listener, eFn) {
		let domListenerWrap = _store.get(dom);
		if(!domListenerWrap) return;
		domListenerWrap.open(listener, eFn);
	}

	this.close = function(dom, listener, eFn) {
		let domListenerWrap = _store.get(dom);
		if(!domListenerWrap) return;
		domListenerWrap.close(listener, eFn);
	}

}

const listenerManager = new ListenerManager(); // 监听管理器实例

function addListener(dom, listener, eFn) {
	listenerManager.add(dom, listener, eFn);
}

function removeListener(dom, listener, eFn) {
	listenerManager.remove(dom, listener, eFn);
}

function openListener(dom, listener, eFn) {
	listenerManager.open(dom, listener, eFn);
}

function closeListener(dom, listener, eFn) {
	listenerManager.close(dom, listener, eFn);
}

export {
	addListener,
	removeListener,
	openListener,
	closeListener,
};